$go2_fail = Proc.new {|error| echo("- #{script.name}: #{error}");exit}
$go2_fail.call('No destination given.') unless script.vars[1]

def go_path(path)
  run, base_id, current = '', Room.current.db_id, Room.current

  while next_room_id = path.shift
    ex = current.wayto[next_room_id]
    cmd = current.wayto[next_room_id]['cmd']
    if cmd.kind_of?(String)
      if ['n','s','e','w','d','u'].include?(cmd) && !ex['door'] && !$go2_exits.include?(current.db_id)
        if run[-1..-1] != cmd
          run += cmd
        else
          if run =~ /(.*?)(\d+)#{cmd}$/
            run = "#{$1}#{$2.to_i + 1}#{cmd}"
          else
            run = run[0..-2] + "2#{cmd}"
          end
        end
        current = Room[next_room_id]
        next unless path.length == 0
      end
      if run.length > 0
        put(run.length > 1 ? "run #{run}" : run)
        run = ''
        tell_wait('go2_step')
        $go2_fail.call("Got lost after run.") unless Room.current.db_id == current.db_id
        return if path.length == 0
      end
      go2_exits(current.db_id) if go2_exit?(current.db_id)
      if ex['door']
        put("open #{cmd}", cmd)
        tell_wait('go2_step')
        $go2_fail.call("Encountered a door problem.") unless Room.current.db_id == next_room_id
        current = Room[next_room_id]
        next
      end
      put(cmd)
      tell_wait('go2_step')
      $go2_fail.call("Encountered a problem with direction '#{cmd}'.") unless Room.current.db_id == next_room_id
    end
    current = Room[next_room_id]
  end
end

def use_portal(portal)
  put("hold '#{portal}'", 'enter')
  match_wait(/Magic walls (bounce) you back|WHOOOOOOOOOOOOSH/) =~ /Magic walls (bounce) you back/
  bounced = !$1.nil?
  put("hold #{Char.held}") if Char.held
  put("dual #{Char.dual}") if Char.dual
  !bounced
end

destination = Map.get_mapping(script.vars[1])
$go2_fail.call("Unknown destination '#{script.vars[1]}'.") if destination.nil?
$go2_fail.call('You are already in that room.') if Room.current.db_id == destination

portale, path = nil, nil
if Room.current.area_id == Room[destination].area_id || Area.all[Room[destination].area_id].start.nil?
  portal, path = Map.use_portal(Room.current.db_id, destination)
  if !portal.nil? && !use_portal(portal)
    path = Map.findpath(Room.current.db_id, destination)
  end
  $go2_fail.call('No portal and no path. Try recall!') if path.nil?
else
  zone_dest = Area.all[Room[destination].area_id].start
  portal, path = Map.use_portal(Room.current.db_id, zone_dest)
  if !portal.nil? && !use_portal(portal)
    path = Map.findpath(Room.current.db_id, zone_dest)
  end
  go_path(path)
  wait_until {Room.current.db_id == zone_dest}
  
  portal, path = Map.use_portal(Room.current.db_id, destination)
  if !portal.nil? && !use_portal(portal)
    path = Map.findpath(Room.current.db_id, destination)
  end
  $go2_fail.call('No portal and no path. Try recall!') if path.nil?
end

go_path(path)